<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<script>
    // a
    function Foo () {
        getName = function () {
            console.log(1);
        }
        return this;
    }
    // b
    Foo.getName = function () {
        console.log(2);
    }
    // c
    Foo.prototype.getName = function () {
        console.log(3);
    }
    // d
    var getName = function () {
        console.log(4);
    }
    // e
    function getName () {
        console.log(5);
    }

    /*
?1.Foo.getName()，Foo为一个函数对象，对象都可以有属性，b 处定义Foo的getName属性为函数，输出2；
?2.getName()，这里看d、e处，d为函数表达式，e为函数声明，两者区别在于变量提升，函数声明的 5 会被后边函数表达式的 4 覆盖；
?3.Foo().getName()，这里要看a处，在Foo内部将全局的getName重新赋值为 console.log(1) 的函数，执行Foo()返回 this，这个this指向window，Foo().getName() 即为window.getName()，输出 1；
?4.getName()，上面3中，全局的getName已经被重新赋值，所以这里依然输出 1；
?5.new Foo.getName()，这里等价于 new (Foo.getName())，先执行 Foo.getName()，输出 2，然后new一个实例；
?6.new Foo().getName()，这里等价于 (new Foo()).getName(), 先new一个Foo的实例，再执行这个实例的getName方法，但是这个实例本身没有这个方法，所以去原型链__protot__上边找，实例.__protot__ === Foo.prototype，所以输出 3；
?7.new new Foo().getName()，这里等价于new (new Foo().getName())，如上述5,6，先输出 3，然后new 一个 new Foo().getName() 的实例。
     */
    Foo.getName();            //? 2
    getName();               //? 4
    Foo().getName();         //? 1
    getName();               //? 1
    new Foo.getName();       //? 2
    new Foo().getName();     //? 3
    new new Foo().getName(); //? 3

</script>
</body>
</html>
